1 // ----------------------------------------------------------------------------
2 // <copyright file=
"PhotonClasses.cs" company="Exit Games GmbH">
3 // PhotonNetwork Framework
for Unity - Copyright (C) 2011 Exit Games GmbH
4 // </copyright>
5 // <summary>
6 //
7 // </summary>
8 // <author>developer@exitgames.com</author>
9 // ----------------------------------------------------------------------------

10
11 #pragma warning disable
1587
12 ///
\file
13 ///
<summary>Wraps up smaller classes that don't need their own file. </summary>
14 ///
15 ///
16 ///
\defgroup publicApi Public API
17 ///
\brief Groups the most important classes that you need to understand early on.
18 ///
19 ///
\defgroup optionalGui Optional Gui Elements
20 ///
\brief Useful GUI elements for PUN.
21 #pragma warning restore
1587
22
23
24 using
System;
25 using
System.Collections.Generic;
26 using
ExitGames.Client.Photon;
27 using
ExitGames.Client.Photon.Lite;
28 using
UnityEngine;
29
30 using
Hashtable = ExitGames.Client.Photon.Hashtable;
31
32
33 ///
<summary>Defines the OnPhotonSerializeView method to make it easy to implement correctly for observable scripts.</summary>
34 ///
\ingroup publicApi
35 public
interface IPunObservable
36 {

37     ///
<summary>
38     ///
Called by PUN several times per second, so that your script can write and read synchronization data for the PhotonView.
39     ///
</summary>
40     ///
<remarks>
41     ///
This method will be called in scripts that are assigned as Observed component of a PhotonView.<br/>
42     ///
PhotonNetwork.sendRateOnSerialize affects how often this method is called.<br/>
43     ///
PhotonNetwork.sendRate affects how often packages are sent by this client.<br/>
44     ///

45     ///
Implementing this method, you can customize which data a PhotonView regularly synchronizes.
46     ///
Your code defines what is being sent (content) and how your data is used by receiving clients.
47     ///

48     ///
Unlike other callbacks, <i>OnPhotonSerializeView only gets called when it is assigned
49     ///
to a PhotonView</i> as PhotonView.observed script.
50     ///

51     ///
To make use of this method, the PhotonStream is essential. It will be in "writing" mode" on the
52     ///
client that controls a PhotonView (PhotonStream.isWriting == true) and in "reading mode" on the
53     ///
remote clients that just receive that the controlling client sends.
54     ///

55     ///
If you skip writing any value into the stream, PUN will skip the update. Used carefully, this can
56     ///
conserve bandwidth and messages (which have a limit per room/second).
57     ///

58     ///
Note that OnPhotonSerializeView is not called on remote clients when the sender does not send
59     ///
any update. This can't be used as "x-times per second Update()".
60     ///
</remarks>
61     ///
\ingroup publicApi
62     
void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info);
63 }

64
65 ///
<summary>
66 ///
Defines all the methods that PUN will call in specific situations, except OnPhotonSerializeView. Implemented by PunBehaviour.
67 ///
</summary>
68 ///
<remarks>
69 ///
PUN will call these methods on any script that implements them, analog to Unity's events and callbacks.
70 ///
The situation that triggers the call is described per method.
71 ///

72 ///
Please simply extend PunBehaviour to implement individual methods.
73 ///

74 ///
OnPhotonSerializeView is NOT called like these callbacks! It's usage frequency is much higher and it is implemented in: IPunObservable.
75 ///
</remarks>
76 ///
\ingroup publicApi
77 public
interface IPunCallbacks
78 {

79     ///
<summary>
80     ///
Called when the initial connection got established but before you can use the server. OnJoinedLobby() or OnConnectedToMaster() are called when PUN is ready.
81     ///
</summary>
82     ///
<remarks>
83     ///
This callback is only useful to detect if the server can be reached at all (technically).
84     ///
Most often, it's enough to implement OnFailedToConnectToPhoton() and OnDisconnectedFromPhoton().
85     ///

86     ///
<i>OnJoinedLobby() or OnConnectedToMaster() are called when PUN is ready.</i>
87     ///

88     ///
When this is called, the low level connection is established and PUN will send your AppId, the user, etc in the background.
89     ///
This is not called for transitions from the masterserver to game servers.
90     ///
</remarks>
91     
void OnConnectedToPhoton();
92
93     ///
<summary>
94     ///
Called when the local user/client left a room.
95     ///
</summary>
96     ///
<remarks>
97     ///
When leaving a room, PUN brings you back to the Master Server.
98     ///
Before you can use lobbies and join or create rooms, OnJoinedLobby() or OnConnectedToMaster() will get called again.
99     ///
</remarks>
100     
void OnLeftRoom();
101
102     ///
<summary>
103     ///
Called after switching to a new MasterClient when the current one leaves. The former already got removed from the player list.
104     ///
</summary>
105     ///
<remarks>
106     ///
This is not called when this client enters a room.
107     ///
</remarks>
108     
void OnMasterClientSwitched(PhotonPlayer newMasterClient);
109
110     ///
<summary>
111     ///
Called when a CreateRoom() call failed. The parameter provides ErrorCode and message (as array).
112     ///
</summary>
113     ///
<remarks>
114     ///
Most likely because the room name is already in use (some other client was faster than you).
115     ///
PUN logs some info if the PhotonNetwork.logLevel is >= PhotonLogLevel.Informational.
116     ///
</remarks>
117     ///
<param name="codeAndMsg">codeAndMsg[0] is an integer ErrorCode and codeAndMsg[1] is a string debug msg.</param>
118     
void OnPhotonCreateRoomFailed(object[] codeAndMsg);
119
120     ///
<summary>
121     ///
Called when a JoinRoom() call failed. The parameter provides ErrorCode and message (as array).
122     ///
</summary>
123     ///
<remarks>
124     ///
Most likely error is that the room does not exist or the room is full (some other client was faster than you).
125     ///
PUN logs some info if the PhotonNetwork.logLevel is >= PhotonLogLevel.Informational.
126     ///
</remarks>
127     ///
<param name="codeAndMsg">codeAndMsg[0] is int ErrorCode. codeAndMsg[1] is string debug msg.</param>
128     
void OnPhotonJoinRoomFailed(object[] codeAndMsg);
129
130     ///
<summary>
131     ///
Called when this client created a room and entered it. OnJoinedRoom() will be called as well.
132     ///
</summary>
133     ///
<remarks>
134     ///
This callback is only called on the client which created a room (see PhotonNetwork.CreateRoom).
135     ///

136     ///
As any client might close (or drop connection) anytime, there is a chance that the
137     ///
creator of a room does not execute OnCreatedRoom.
138     ///

139     ///
If you need specific room properties or a "start signal", it is safer to implement
140     ///
OnMasterClientSwitched() and to make the new MasterClient check the room's state.
141     ///
</remarks>
142     
void OnCreatedRoom();
143
144     ///
<summary>
145     ///
Called on entering a lobby on the Master Server. The actual room-list updates will call OnReceivedRoomListUpdate().
146     ///
</summary>
147     ///
<remarks>
148     ///
Note: When PhotonNetwork.autoJoinLobby is false, OnConnectedToMaster() will be called and the room list won't become available.
149     ///

150     ///
While in the lobby, the roomlist is automatically updated in fixed intervals (which you can't modify).
151     ///
</remarks>
152     
void OnJoinedLobby();
153
154     ///
<summary>
155     ///
Called after leaving a lobby.
156     ///
</summary>
157     ///
<remarks>
158     ///
When you leave a lobby, [CreateRoom](@ref PhotonNetwork.CreateRoom) and [JoinRandomRoom](@ref PhotonNetwork.JoinRandomRoom)
159     ///
automatically refer to the default lobby.
160     ///
</remarks>
161     
void OnLeftLobby();
162
163     ///
<summary>
164     ///
Called if a connect call to the Photon server failed before the connection was established, followed by a call to OnDisconnectedFromPhoton().
165     ///
</summary>
166     ///
<remarks>
167     ///
This is called when no connection could be established at all.
168     ///
It differs from OnConnectionFail, which is called when an existing connection fails.
169     ///
</remarks>
170     
void OnFailedToConnectToPhoton(DisconnectCause cause);
171
172     ///
<summary>
173     ///
Called when something causes the connection to fail (after it was established), followed by a call to OnDisconnectedFromPhoton().
174     ///
</summary>
175     ///
<remarks>
176     ///
If the server could not be reached in the first place, OnFailedToConnectToPhoton is called instead.
177     ///
The reason for the error is provided as DisconnectCause.
178     ///
</remarks>
179     
void OnConnectionFail(DisconnectCause cause);
180
181     ///
<summary>
182     ///
Called after disconnecting from the Photon server.
183     ///
</summary>
184     ///
<remarks>
185     ///
In some cases, other callbacks are called before OnDisconnectedFromPhoton is called.
186     ///
Examples: OnConnectionFail() and OnFailedToConnectToPhoton().
187     ///
</remarks>
188     
void OnDisconnectedFromPhoton();
189
190     ///
<summary>
191     ///
Called on all scripts on a GameObject (and children) that have been Instantiated using PhotonNetwork.Instantiate.
192     ///
</summary>
193     ///
<remarks>
194     ///
PhotonMessageInfo parameter provides info about who created the object and when (based off PhotonNetworking.time).
195     ///
</remarks>
196     
void OnPhotonInstantiate(PhotonMessageInfo info);
197
198     ///
<summary>
199     ///
Called for any update of the room listing (no matter if "new" list or "update for known" list). Only called in the Lobby state (on master server).
200     ///
</summary>
201     ///
<remarks>
202     ///
Not all types of lobbies provive a listing of rooms to the client. Some are silent and specialized for server-side matchmaking.
203     ///

204     ///
PUN provides the list of rooms by PhotonNetwork.GetRoomList().<br/>
205     ///
Each item is a RoomInfo which might include custom properties (provided you defined those as lobby-listed when creating a room).
206     ///
</remarks>
207     
void OnReceivedRoomListUpdate();
208
209     ///
<summary>
210     ///
Called when entering a room (by creating or joining it). Called on all clients (including the Master Client).
211     ///
</summary>
212     ///
<remarks>
213     ///
This method is commonly used to instantiate player characters.
214     ///
If a match has to be started "actively", you can call an [RPC](@ref PhotonView.RPC) triggered by a user's button-press or a timer.
215     ///

216     ///
When this is called, you can usually already access the existing players in the room via PhotonNetwork.playerList.
217     ///
Also, all custom properties should be already available as Room.customProperties. Check Room.playerCount to find out if
218     ///
enough players are in the room to start playing.
219     ///
</remarks>
220     
void OnJoinedRoom();
221
222     ///
<summary>
223     ///
Called when a remote player entered the room. This PhotonPlayer is already added to the playerlist at this time.
224     ///
</summary>
225     ///
<remarks>
226     ///
If your game starts with a certain number of players, this callback can be useful to check the
227     ///
Room.playerCount and find out if you can start.
228     ///
</remarks>
229     
void OnPhotonPlayerConnected(PhotonPlayer newPlayer);
230
231     ///
<summary>
232     ///
Called when a remote player left the room. This PhotonPlayer is already removed from the playerlist at this time.
233     ///
</summary>
234     ///
<remarks>
235     ///
When your client calls PhotonNetwork.leaveRoom, PUN will call this method on the remaining clients.
236     ///
When a remote client drops connection or gets closed, this callback gets executed. after a timeout
237     ///
of several seconds.
238     ///
</remarks>
239     
void OnPhotonPlayerDisconnected(PhotonPlayer otherPlayer);
240
241     ///
<summary>
242     ///
Called when a JoinRandom() call failed. The parameter provides ErrorCode and message.
243     ///
</summary>
244     ///
<remarks>
245     ///
Most likely all rooms are full or no rooms are available. <br/>
246     ///
When using multiple lobbies (via JoinLobby or TypedLobby), another lobby might have more/fitting rooms.<br/>
247     ///
PUN logs some info if the PhotonNetwork.logLevel is >= PhotonLogLevel.Informational.
248     ///
</remarks>
249     ///
<param name="codeAndMsg">codeAndMsg[0] is int ErrorCode. codeAndMsg[1] is string debug msg.</param>
250     
void OnPhotonRandomJoinFailed(object[] codeAndMsg);
251
252     ///
<summary>
253     ///
Called after the connection to the master is established and authenticated but only when PhotonNetwork.autoJoinLobby is false.
254     ///
</summary>
255     ///
<remarks>
256     ///
If you set PhotonNetwork.autoJoinLobby to true, OnJoinedLobby() will be called instead of this.
257     ///

258     ///
You can join rooms and create them even without being in a lobby. The default lobby is used in that case.
259     ///
The list of available rooms won't become available unless you join a lobby via PhotonNetwork.joinLobby.
260     ///
</remarks>
261     
void OnConnectedToMaster();
262
263     ///
<summary>
264     ///
Because the concurrent user limit was (temporarily) reached, this client is rejected by the server and disconnecting.
265     ///
</summary>
266     ///
<remarks>
267     ///
When this happens, the user might try again later. You can't create or join rooms in OnPhotonMaxCcuReached(), cause the client will be disconnecting.
268     ///
You can raise the CCU limits with a new license (when you host yourself) or extended subscription (when using the Photon Cloud).
269     ///
The Photon Cloud will mail you when the CCU limit was reached. This is also visible in the Dashboard (webpage).
270     ///
</remarks>
271     
void OnPhotonMaxCccuReached();
272
273     ///
<summary>
274     ///
Called when a room's custom properties changed. The propertiesThatChanged contains all that was set via Room.SetCustomProperties.
275     ///
</summary>
276     ///
<remarks>
277     ///
Since v1.25 this method has one parameter: Hashtable propertiesThatChanged.<br/>
278     ///
Changing properties must be done by Room.SetCustomProperties, which causes this callback locally, too.
279     ///
</remarks>
280     ///
<param name="propertiesThatChanged"></param>
281     
void OnPhotonCustomRoomPropertiesChanged(Hashtable propertiesThatChanged);
282
283     ///
<summary>
284     ///
Called when custom player-properties are changed. Player and the changed properties are passed as object[].
285     ///
</summary>
286     ///
<remarks>
287     ///
Since v1.25 this method has one parameter: object[] playerAndUpdatedProps, which contains two entries.<br/>
288     ///
[0] is the affected PhotonPlayer.<br/>
289     ///
[1] is the Hashtable of properties that changed.<br/>
290     ///

291     ///
We are using a object[] due to limitations of Unity's GameObject.SendMessage (which has only one optional parameter).
292     ///
293     ///
Changing properties must be done by PhotonPlayer.SetCustomProperties, which causes this callback locally, too.
294     ///

295     ///
Example:<pre>
296     ///
void OnPhotonPlayerPropertiesChanged(object[] playerAndUpdatedProps) {
297     ///
PhotonPlayer player = playerAndUpdatedProps[0] as PhotonPlayer;
298     ///
Hashtable props = playerAndUpdatedProps[1] as Hashtable;
299     ///
//...
300     ///
}</pre>
301     ///
</remarks>
302     ///
<param name="playerAndUpdatedProps">Contains PhotonPlayer and the properties that changed See remarks.</param>
303     
void OnPhotonPlayerPropertiesChanged(object[] playerAndUpdatedProps);
304
305     ///
<summary>
306     ///
Called when the server sent the response to a FindFriends request and updated PhotonNetwork.Friends.
307     ///
</summary>
308     ///
<remarks>
309     ///
The friends list is available as PhotonNetwork.Friends, listing name, online state and
310     ///
the room a user is in (if any).
311     ///
</remarks>
312     
void OnUpdatedFriendList();
313
314     ///
<summary>
315     ///
Called when the custom authentication failed. Followed by disconnect!
316     ///
</summary>
317     ///
<remarks>
318     ///
Custom Authentication can fail due to user-input, bad tokens/secrets.
319     ///
If authentication is successful, this method is not called. Implement OnJoinedLobby() or OnConnectedToMaster() (as usual).
320     ///

321     ///
During development of a game, it might also fail due to wrong configuration on the server side.
322     ///
In those cases, logging the debugMessage is very important.
323     ///

324     ///
Unless you setup a custom authentication service for your app (in the [Dashboard](https://cloud.exitgames.com/dashboard)),
325     ///
this won't be called!
326     ///
</remarks>
327     ///
<param name="debugMessage">Contains a debug message why authentication failed. This has to be fixed during development time.</param>
328     
void OnCustomAuthenticationFailed(string debugMessage);
329
330     ///
<summary>
331     ///
Called by PUN when the response to a WebRPC is available. See PhotonNetwork.WebRPC.
332     ///
</summary>
333     ///
<remarks>
334     ///
Important: The response.ReturnCode is 0 if Photon was able to reach your web-service.
335     ///
The content of the response is what your web-service sent. You can create a WebResponse instance from it.
336     ///
Example: WebRpcResponse webResponse = new WebRpcResponse(operationResponse);
337     ///
338     ///
Please note: Class OperationResponse is in a namespace which needs to be "used":
339     ///
using ExitGames.Client.Photon; // includes OperationResponse (and other classes)
340     ///
341     ///
The OperationResponse.ReturnCode by Photon is:<pre>
342     ///
0 for "OK"
343     ///
-3 for "Web-Service not configured" (see Dashboard / WebHooks)
344     ///
-5 for "Web-Service does now have RPC path/name" (at least for Azure)</pre>
345     ///
</remarks>
346     
void OnWebRpcResponse(OperationResponse response);
347
348     ///
<summary>
349     ///
Called when another player requests ownership of a PhotonView from you (the current owner).
350     ///
</summary>
351     ///
<remarks>
352     ///
The parameter viewAndPlayer contains:
353     ///

354     ///
PhotonView view = viewAndPlayer[0] as PhotonView;
355     ///

356     ///
PhotonPlayer requestingPlayer = viewAndPlayer[1] as PhotonPlayer;
357     ///
</remarks>
358     ///
<param name="viewAndPlayer">The PhotonView is viewAndPlayer[0] and the requesting player is viewAndPlayer[1].</param>
359     
void OnOwnershipRequest(object[] viewAndPlayer);
360 }

361
362
363 namespace
Photon
364 {
365     
using Hashtable = ExitGames.Client.Photon.Hashtable;
366
367     ///
<summary>
368     ///
This class adds the property photonView, while logging a warning when your game still uses the networkView.
369     ///
</summary>
370     
public class MonoBehaviour : UnityEngine.MonoBehaviour
371     {
372         
public PhotonView photonView
373         {
374             
get
375             {
376                 
return PhotonView.Get(this);
377             }
378         }
379
380         
new public PhotonView networkView
381         {
382             
get
383             {
384                 Debug.LogWarning("
Why are you still using networkView? should be PhotonView?");
385                 
return PhotonView.Get(this);
386             }
387         }
388     }

389
390
391     ///
<summary>
392     ///
This class provides a .photonView and all callbacks/events that PUN can call. Override the events/methods you want to use.
393     ///
</summary>
394     ///
<remarks>
395     ///
This class implements IPunCallbacks where the callback methods are described.
396     ///
By extending this class, you can implement individual methods as override.
397     ///
Visual Studio and MonoDevelop should provide the list of methods when you begin typing "override".
398     ///
Your implementation does not have to call "base.method()".
399     ///
</remarks>
400     ///
\ingroup publicApi
401     
// the documentation for the interface methods becomes inherited when Doxygen builds it.
402     
public class PunBehaviour : Photon.MonoBehaviour, IPunCallbacks
403     {

404         ///
<summary>
405         ///
Called when the initial connection got established but before you can use the server. OnJoinedLobby() or OnConnectedToMaster() are called when PUN is ready.
406         ///
</summary>
407         ///
<remarks>
408         ///
This callback is only useful to detect if the server can be reached at all (technically).
409         ///
Most often, it's enough to implement OnFailedToConnectToPhoton() and OnDisconnectedFromPhoton().
410         ///

411         ///
<i>OnJoinedLobby() or OnConnectedToMaster() are called when PUN is ready.</i>
412         ///

413         ///
When this is called, the low level connection is established and PUN will send your AppId, the user, etc in the background.
414         ///
This is not called for transitions from the masterserver to game servers.
415         ///
</remarks>
416         
public virtual void OnConnectedToPhoton()
417         {
418         }

419
420         ///
<summary>
421         ///
Called when the local user/client left a room.
422         ///
</summary>
423         ///
<remarks>
424         ///
When leaving a room, PUN brings you back to the Master Server.
425         ///
Before you can use lobbies and join or create rooms, OnJoinedLobby() or OnConnectedToMaster() will get called again.
426         ///
</remarks>
427         
public virtual void OnLeftRoom()
428         {
429         }

430
431         ///
<summary>
432         ///
Called after switching to a new MasterClient when the current one leaves. The former already got removed from the player list.
433         ///
</summary>
434         ///
<remarks>
435         ///
This is not called when this client enters a room.
436         ///
</remarks>
437         
public virtual void OnMasterClientSwitched(PhotonPlayer newMasterClient)
438         {
439         }

440
441         ///
<summary>
442         ///
Called when a CreateRoom() call failed. The parameter provides ErrorCode and message (as array).
443         ///
</summary>
444         ///
<remarks>
445         ///
Most likely because the room name is already in use (some other client was faster than you).
446         ///
PUN logs some info if the PhotonNetwork.logLevel is >= PhotonLogLevel.Informational.
447         ///
</remarks>
448         ///
<param name="codeAndMsg">codeAndMsg[0] is an integer ErrorCode and codeAndMsg[1] is a string debug msg.</param>
449         
public virtual void OnPhotonCreateRoomFailed(object[] codeAndMsg)
450         {
451         }

452
453         ///
<summary>
454         ///
Called when a JoinRoom() call failed. The parameter provides ErrorCode and message (as array).
455         ///
</summary>
456         ///
<remarks>
457         ///
Most likely error is that the room does not exist or the room is full (some other client was faster than you).
458         ///
PUN logs some info if the PhotonNetwork.logLevel is >= PhotonLogLevel.Informational.
459         ///
</remarks>
460         ///
<param name="codeAndMsg">codeAndMsg[0] is int ErrorCode. codeAndMsg[1] is string debug msg.</param>
461         
public virtual void OnPhotonJoinRoomFailed(object[] codeAndMsg)
462         {
463         }

464
465         ///
<summary>
466         ///
Called when this client created a room and entered it. OnJoinedRoom() will be called as well.
467         ///
</summary>
468         ///
<remarks>
469         ///
This callback is only called on the client which created a room (see PhotonNetwork.CreateRoom).
470         ///

471         ///
As any client might close (or drop connection) anytime, there is a chance that the
472         ///
creator of a room does not execute OnCreatedRoom.
473         ///

474         ///
If you need specific room properties or a "start signal", it is safer to implement
475         ///
OnMasterClientSwitched() and to make the new MasterClient check the room's state.
476         ///
</remarks>
477         
public virtual void OnCreatedRoom()
478         {
479         }

480
481         ///
<summary>
482         ///
Called on entering a lobby on the Master Server. The actual room-list updates will call OnReceivedRoomListUpdate().
483         ///
</summary>
484         ///
<remarks>
485         ///
Note: When PhotonNetwork.autoJoinLobby is false, OnConnectedToMaster() will be called and the room list won't become available.
486         ///

487         ///
While in the lobby, the roomlist is automatically updated in fixed intervals (which you can't modify).
488         ///
</remarks>
489         
public virtual void OnJoinedLobby()
490         {
491         }

492
493         ///
<summary>
494         ///
Called after leaving a lobby.
495         ///
</summary>
496         ///
<remarks>
497         ///
When you leave a lobby, [CreateRoom](@ref PhotonNetwork.CreateRoom) and [JoinRandomRoom](@ref PhotonNetwork.JoinRandomRoom)
498         ///
automatically refer to the default lobby.
499         ///
</remarks>
500         
public virtual void OnLeftLobby()
501         {
502         }

503
504         ///
<summary>
505         ///
Called if a connect call to the Photon server failed before the connection was established, followed by a call to OnDisconnectedFromPhoton().
506         ///
</summary>
507         ///
<remarks>
508         ///
This is called when no connection could be established at all.
509         ///
It differs from OnConnectionFail, which is called when an existing connection fails.
510         ///
</remarks>
511         
public virtual void OnFailedToConnectToPhoton(DisconnectCause cause)
512         {
513         }

514
515         ///
<summary>
516         ///
Called after disconnecting from the Photon server.
517         ///
</summary>
518         ///
<remarks>
519         ///
In some cases, other callbacks are called before OnDisconnectedFromPhoton is called.
520         ///
Examples: OnConnectionFail() and OnFailedToConnectToPhoton().
521         ///
</remarks>
522         
public virtual void OnDisconnectedFromPhoton()
523         {
524         }

525
526         ///
<summary>
527         ///
Called when something causes the connection to fail (after it was established), followed by a call to OnDisconnectedFromPhoton().
528         ///
</summary>
529         ///
<remarks>
530         ///
If the server could not be reached in the first place, OnFailedToConnectToPhoton is called instead.
531         ///
The reason for the error is provided as DisconnectCause.
532         ///
</remarks>
533         
public virtual void OnConnectionFail(DisconnectCause cause)
534         {
535         }

536
537         ///
<summary>
538         ///
Called on all scripts on a GameObject (and children) that have been Instantiated using PhotonNetwork.Instantiate.
539         ///
</summary>
540         ///
<remarks>
541         ///
PhotonMessageInfo parameter provides info about who created the object and when (based off PhotonNetworking.time).
542         ///
</remarks>
543         
public virtual void OnPhotonInstantiate(PhotonMessageInfo info)
544         {
545         }

546
547         ///
<summary>
548         ///
Called for any update of the room listing (no matter if "new" list or "update for known" list). Only called in the Lobby state (on master server).
549         ///
</summary>
550         ///
<remarks>
551         ///
Not all types of lobbies provive a listing of rooms to the client. Some are silent and specialized for server-side matchmaking.
552         ///

553         ///
PUN provides the list of rooms by PhotonNetwork.GetRoomList().<br/>
554         ///
Each item is a RoomInfo which might include custom properties (provided you defined those as lobby-listed when creating a room).
555         ///
</remarks>
556         
public virtual void OnReceivedRoomListUpdate()
557         {
558         }

559
560         ///
<summary>
561         ///
Called when entering a room (by creating or joining it). Called on all clients (including the Master Client).
562         ///
</summary>
563         ///
<remarks>
564         ///
This method is commonly used to instantiate player characters.
565         ///
If a match has to be started "actively", you can call an [RPC](@ref PhotonView.RPC) triggered by a user's button-press or a timer.
566         ///

567         ///
When this is called, you can usually already access the existing players in the room via PhotonNetwork.playerList.
568         ///
Also, all custom properties should be already available as Room.customProperties. Check Room.playerCount to find out if
569         ///
enough players are in the room to start playing.
570         ///
</remarks>
571         
public virtual void OnJoinedRoom()
572         {
573         }

574
575         ///
<summary>
576         ///
Called when a remote player entered the room. This PhotonPlayer is already added to the playerlist at this time.
577         ///
</summary>
578         ///
<remarks>
579         ///
If your game starts with a certain number of players, this callback can be useful to check the
580         ///
Room.playerCount and find out if you can start.
581         ///
</remarks>
582         
public virtual void OnPhotonPlayerConnected(PhotonPlayer newPlayer)
583         {
584         }

585
586         ///
<summary>
587         ///
Called when a remote player left the room. This PhotonPlayer is already removed from the playerlist at this time.
588         ///
</summary>
589         ///
<remarks>
590         ///
When your client calls PhotonNetwork.leaveRoom, PUN will call this method on the remaining clients.
591         ///
When a remote client drops connection or gets closed, this callback gets executed. after a timeout
592         ///
of several seconds.
593         ///
</remarks>
594         
public virtual void OnPhotonPlayerDisconnected(PhotonPlayer otherPlayer)
595         {
596         }

597
598         ///
<summary>
599         ///
Called when a JoinRandom() call failed. The parameter provides ErrorCode and message.
600         ///
</summary>
601         ///
<remarks>
602         ///
Most likely all rooms are full or no rooms are available. <br/>
603         ///
When using multiple lobbies (via JoinLobby or TypedLobby), another lobby might have more/fitting rooms.<br/>
604         ///
PUN logs some info if the PhotonNetwork.logLevel is >= PhotonLogLevel.Informational.
605         ///
</remarks>
606         ///
<param name="codeAndMsg">codeAndMsg[0] is int ErrorCode. codeAndMsg[1] is string debug msg.</param>
607         
public virtual void OnPhotonRandomJoinFailed(object[] codeAndMsg)
608         {
609         }

610
611         ///
<summary>
612         ///
Called after the connection to the master is established and authenticated but only when PhotonNetwork.autoJoinLobby is false.
613         ///
</summary>
614         ///
<remarks>
615         ///
If you set PhotonNetwork.autoJoinLobby to true, OnJoinedLobby() will be called instead of this.
616         ///

617         ///
You can join rooms and create them even without being in a lobby. The default lobby is used in that case.
618         ///
The list of available rooms won't become available unless you join a lobby via PhotonNetwork.joinLobby.
619         ///
</remarks>
620         
public virtual void OnConnectedToMaster()
621         {
622         }

623
624         ///
<summary>
625         ///
Because the concurrent user limit was (temporarily) reached, this client is rejected by the server and disconnecting.
626         ///
</summary>
627         ///
<remarks>
628         ///
When this happens, the user might try again later. You can't create or join rooms in OnPhotonMaxCcuReached(), cause the client will be disconnecting.
629         ///
You can raise the CCU limits with a new license (when you host yourself) or extended subscription (when using the Photon Cloud).
630         ///
The Photon Cloud will mail you when the CCU limit was reached. This is also visible in the Dashboard (webpage).
631         ///
</remarks>
632         
public virtual void OnPhotonMaxCccuReached()
633         {
634         }

635
636         ///
<summary>
637         ///
Called when a room's custom properties changed. The propertiesThatChanged contains all that was set via Room.SetCustomProperties.
638         ///
</summary>
639         ///
<remarks>
640         ///
Since v1.25 this method has one parameter: Hashtable propertiesThatChanged.<br/>
641         ///
Changing properties must be done by Room.SetCustomProperties, which causes this callback locally, too.
642         ///
</remarks>
643         ///
<param name="propertiesThatChanged"></param>
644         
public virtual void OnPhotonCustomRoomPropertiesChanged(Hashtable propertiesThatChanged)
645         {
646         }

647
648         ///
<summary>
649         ///
Called when custom player-properties are changed. Player and the changed properties are passed as object[].
650         ///
</summary>
651         ///
<remarks>
652         ///
Since v1.25 this method has one parameter: object[] playerAndUpdatedProps, which contains two entries.<br/>
653         ///
[0] is the affected PhotonPlayer.<br/>
654         ///
[1] is the Hashtable of properties that changed.<br/>
655         ///

656         ///
We are using a object[] due to limitations of Unity's GameObject.SendMessage (which has only one optional parameter).
657         ///
658         ///
Changing properties must be done by PhotonPlayer.SetCustomProperties, which causes this callback locally, too.
659         ///

660         ///
Example:<pre>
661         ///
void OnPhotonPlayerPropertiesChanged(object[] playerAndUpdatedProps) {
662         ///
PhotonPlayer player = playerAndUpdatedProps[0] as PhotonPlayer;
663         ///
Hashtable props = playerAndUpdatedProps[1] as Hashtable;
664         ///
//...
665         ///
}</pre>
666         ///
</remarks>
667         ///
<param name="playerAndUpdatedProps">Contains PhotonPlayer and the properties that changed See remarks.</param>
668         
public virtual void OnPhotonPlayerPropertiesChanged(object[] playerAndUpdatedProps)
669         {
670         }

671
672         ///
<summary>
673         ///
Called when the server sent the response to a FindFriends request and updated PhotonNetwork.Friends.
674         ///
</summary>
675         ///
<remarks>
676         ///
The friends list is available as PhotonNetwork.Friends, listing name, online state and
677         ///
the room a user is in (if any).
678         ///
</remarks>
679         
public virtual void OnUpdatedFriendList()
680         {
681         }

682
683         ///
<summary>
684         ///
Called when the custom authentication failed. Followed by disconnect!
685         ///
</summary>
686         ///
<remarks>
687         ///
Custom Authentication can fail due to user-input, bad tokens/secrets.
688         ///
If authentication is successful, this method is not called. Implement OnJoinedLobby() or OnConnectedToMaster() (as usual).
689         ///

690         ///
During development of a game, it might also fail due to wrong configuration on the server side.
691         ///
In those cases, logging the debugMessage is very important.
692         ///

693         ///
Unless you setup a custom authentication service for your app (in the [Dashboard](https://cloud.exitgames.com/dashboard)),
694         ///
this won't be called!
695         ///
</remarks>
696         ///
<param name="debugMessage">Contains a debug message why authentication failed. This has to be fixed during development time.</param>
697         
public virtual void OnCustomAuthenticationFailed(string debugMessage)
698         {
699         }

700
701         ///
<summary>
702         ///
Called by PUN when the response to a WebRPC is available. See PhotonNetwork.WebRPC.
703         ///
</summary>
704         ///
<remarks>
705         ///
Important: The response.ReturnCode is 0 if Photon was able to reach your web-service.
706         ///
The content of the response is what your web-service sent. You can create a WebResponse instance from it.
707         ///
Example: WebRpcResponse webResponse = new WebRpcResponse(operationResponse);
708         ///
709         ///
Please note: Class OperationResponse is in a namespace which needs to be "used":
710         ///
using ExitGames.Client.Photon; // includes OperationResponse (and other classes)
711         ///
712         ///
The OperationResponse.ReturnCode by Photon is:<pre>
713         ///
0 for "OK"
714         ///
-3 for "Web-Service not configured" (see Dashboard / WebHooks)
715         ///
-5 for "Web-Service does now have RPC path/name" (at least for Azure)</pre>
716         ///
</remarks>
717         
public virtual void OnWebRpcResponse(OperationResponse response)
718         {
719         }

720
721         ///
<summary>
722         ///
Called when another player requests ownership of a PhotonView from you (the current owner).
723         ///
</summary>
724         ///
<remarks>
725         ///
The parameter viewAndPlayer contains:
726         ///

727         ///
PhotonView view = viewAndPlayer[0] as PhotonView;
728         ///

729         ///
PhotonPlayer requestingPlayer = viewAndPlayer[1] as PhotonPlayer;
730         ///
</remarks>
731         ///
<param name="viewAndPlayer">The PhotonView is viewAndPlayer[0] and the requesting player is viewAndPlayer[1].</param>
732         
public virtual void OnOwnershipRequest(object[] viewAndPlayer)
733         {
734         }
735     }
736 }

737
738
739 ///
<summary>
740 ///
Container class for info about a particular message, RPC or update.
741 ///
</summary>
742 ///
\ingroup publicApi
743 public
class PhotonMessageInfo
744 {
745     
private int timeInt;
746     
public PhotonPlayer sender;
747     
public PhotonView photonView;
748
749     ///
<summary>
750     ///
Initializes a new instance of the <see cref="PhotonMessageInfo"/> class.
751     ///
To create an empty messageinfo only!
752     ///
</summary>
753     
public PhotonMessageInfo()
754     {
755         
this.sender = PhotonNetwork.player;
756         
this.timeInt = (int)(PhotonNetwork.time * 1000);
757         
this.photonView = null;
758     }
759
760     
public PhotonMessageInfo(PhotonPlayer player, int timestamp, PhotonView view)
761     {
762         
this.sender = player;
763         
this.timeInt = timestamp;
764         
this.photonView = view;
765     }
766
767     
public double timestamp
768     {
769         
get { return ((double)(uint)this.timeInt) / 1000.0f; }
770     }
771
772     
public override string ToString()
773     {
774         
return string.Format("[PhotonMessageInfo: Sender='{1}' Senttime={0}]", this.timestamp, this.sender);
775     }
776 }

777
778 ///
<summary>Wraps up common room properties needed when you create rooms.</summary>
779 ///
<remarks>This directly maps to what the fields in the Room class.</remarks>
780 public
class RoomOptions
781 {

782     ///
<summary>Max number of players that can be in the room at any time. 0 means "no limit".</summary>
783     
public int maxPlayers;
784
785     ///
<summary>Defines if this room is listed in the lobby. If not, it also is not joined randomly.</summary>
786     ///
<remarks>
787     ///
A room that is not visible will be excluded from the room lists that are sent to the clients in lobbies.
788     ///
An invisible room can be joined by name but is excluded from random matchmaking.
789     ///
790     ///
Use this to "hide" a room and simulate "private rooms". Players can exchange a roomname and create it
791     ///
invisble to avoid anyone else joining it.
792     ///
</remarks>
793     
public bool isVisible { get { return this.isVisibleField; } set { this.isVisibleField = value; } }
794     
private bool isVisibleField = true;
795
796     ///
<summary>Defines if this room can be joined at all.</summary>
797     ///
<remarks>
798     ///
If a room is closed, no player can join this. As example this makes sense when 3 of 4 possible players
799     ///
start their gameplay early and don't want anyone to join during the game.
800     ///
The room can still be listed in the lobby (set isVisible to control lobby-visibility).
801     ///
</remarks>
802     
public bool isOpen { get { return this.isOpenField; } set { this.isOpenField = value; } }
803     
private bool isOpenField = true;
804
805     ///
<summary>Removes a user's events and properties from the room when a user leaves.</summary>
806     ///
<remarks>
807     ///
This makes sense when in rooms where players can't place items in the room and just vanish entirely.
808     ///
When you disable this, the event history can become too long to load if the room stays in use indefinitely.
809     ///
Default: true. Cleans up the cache and props of leaving users.
810     ///
</remarks>
811     
public bool cleanupCacheOnLeave { get { return this.cleanupCacheOnLeaveField; } set { this.cleanupCacheOnLeaveField = value; } }
812     
private bool cleanupCacheOnLeaveField = PhotonNetwork.autoCleanUpPlayerObjects;
813
814     ///
<summary>The room's custom properties to set. Use string keys!</summary>
815     ///
<remarks>
816     ///
Custom room properties are any key-values you need to define the game's setup.
817     ///
The shorter your keys are, the better.
818     ///
Example: Map, Mode (could be "m" when used with "Map"), TileSet (could be "t").
819     ///
</remarks>
820     
public Hashtable customRoomProperties;
821
822     ///
<summary>Defines the custom room properties that get listed in the lobby.</summary>
823     ///
<remarks>
824     ///
Name the custom room properties that should be available to clients that are in a lobby.
825     ///
Use with care. Unless a custom property is essential for matchmaking or user info, it should
826     ///
not be sent to the lobby, which causes traffic and delays for clients in the lobby.
827     ///
828     ///
Default: No custom properties are sent to the lobby.
829     ///
</remarks>
830     
public string[] customRoomPropertiesForLobby = new string[0];
831
832     ///
<summary>Time To Live (TTL) for an 'actor' in a room. If a client disconnects, this actor is inactive first and removed after this timeout. In milliseconds.</summary>
833     
//public int PlayerTtl;
834 }

835
836
837 ///
<summary>Refers to a specific lobby (and type) on the server.</summary>
838 ///
<remarks>
839 ///
The name and type are the unique identifier for a lobby.<br/>
840 ///
Join a lobby via PhotonNetwork.JoinLobby(TypedLobby lobby).<br/>
841 ///
The current lobby is stored in PhotonNetwork.lobby.
842 ///
</remarks>
843 public
class TypedLobby
844 {

845     ///
<summary>
846     ///
The name of the Lobby. Can be any string. Default lobby uses "".
847     ///
</summary>
848     
public string Name;
849
850     ///
<summary>
851     ///
The type of the Lobby. Default lobby uses LobbyType.Default.
852     ///
</summary>
853     
public LobbyType Type;
854
855     
public static readonly TypedLobby Default = new TypedLobby();
856     
public bool IsDefault { get { return this.Type == LobbyType.Default && string.IsNullOrEmpty(this.Name); } }
857
858     
public TypedLobby()
859     {
860         
this.Name = string.Empty;
861         
this.Type = LobbyType.Default;
862     }
863
864     
public TypedLobby(string name, LobbyType type)
865     {
866         
this.Name = name;
867         
this.Type = type;
868     }
869
870     
public override string ToString()
871     {
872         
return string.Format("Lobby '{0}'[{1}]", this.Name, this.Type);
873     }
874 }

875
876
877 ///
<summary>Aggregates several less-often used options for operation RaiseEvent. See field descriptions for usage details.</summary>
878 public
class RaiseEventOptions
879 {

880     ///
<summary>Default options: CachingOption: DoNotCache, InterestGroup: 0, targetActors: null, receivers: Others, sequenceChannel: 0.</summary>
881     
public readonly static RaiseEventOptions Default = new RaiseEventOptions();
882
883     ///
<summary>Defines if the server should simply send the event, put it in the cache or remove events that are like this one.</summary>
884     ///
<remarks>
885     ///
When using option: SliceSetIndex, SlicePurgeIndex or SlicePurgeUpToIndex, set a CacheSliceIndex. All other options except SequenceChannel get ignored.
886     ///
</remarks>
887     
public EventCaching CachingOption;
888
889     ///
<summary>The number of the Interest Group to send this to. 0 goes to all users but to get 1 and up, clients must subscribe to the group first.</summary>
890     
public byte InterestGroup;
891
892     ///
<summary>A list of PhotonPlayer.IDs to send this event to. You can implement events that just go to specific users this way.</summary>
893     
public int[] TargetActors;
894
895     ///
<summary>Sends the event to All, MasterClient or Others (default). Be careful with MasterClient, as the client might disconnect before it got the event and it gets lost.</summary>
896     
public ReceiverGroup Receivers;
897
898     ///
<summary>Events are ordered per "channel". If you have events that are independent of others, they can go into another sequence or channel.</summary>
899     
public byte SequenceChannel;
900
901     ///
<summary>Events can be forwarded to Webhooks, which can evaluate and use the events to follow the game's state.</summary>
902     
public bool ForwardToWebhook;
903
904     ///
<summary>Used along with CachingOption SliceSetIndex, SlicePurgeIndex or SlicePurgeUpToIndex if you want to set or purge a specific cache-slice.</summary>
905     
public int CacheSliceIndex;
906
907     ///
<summary>Use rarely. The binary message gets encrpted before being sent. Any receiver in the room will be able to decrypt the message, of course.</summary>
908     
public bool Encrypt;
909 }

910
911 ///
<summary>Defines Photon event-codes as used by PUN.</summary>
912 internal
class PunEvent
913 {
914     
public const byte RPC = 200;
915     
public const byte SendSerialize = 201;
916     
public const byte Instantiation = 202;
917     
public const byte CloseConnection = 203;
918     
public const byte Destroy = 204;
919     
public const byte RemoveCachedRPCs = 205;
920     
public const byte SendSerializeReliable = 206; // TS: added this but it's not really needed anymore
921     
public const byte DestroyPlayer = 207; // TS: added to make others remove all GOs of a player
922     
public const byte AssignMaster = 208; // TS: added to assign someone master client (overriding the current)
923     
public const byte OwnershipRequest = 209;
924     
public const byte OwnershipTransfer = 210;
925     
public const byte VacantViewIds = 211;
926 }

927
928 ///
<summary>
929 ///
This container is used in OnPhotonSerializeView() to either provide incoming data of a PhotonView or for you to provide it.
930 ///
</summary>
931 ///
<remarks>
932 ///
The isWriting property will be true if this client is the "owner" of the PhotonView (and thus the GameObject).
933 ///
Add data to the stream and it's sent via the server to the other players in a room.
934 ///
On the receiving side, isWriting is false and the data should be read.
935 ///
936 ///
Send as few data as possible to keep connection quality up. An empty PhotonStream will not be sent.
937 ///
938 ///
Use either Serialize() for reading and writing or SendNext() and ReceiveNext(). The latter two are just explicit read and
939 ///
write methods but do about the same work as Serialize(). It's a matter of preference which methods you use.
940 ///
</remarks>
941 ///
<seealso cref="PhotonNetworkingMessage"/>
942 ///
\ingroup publicApi
943 public
class PhotonStream
944 {
945     
bool write = false;
946     
internal List<object> data;
947     
byte currentItem = 0; //Used to track the next item to receive.
948
949     ///
<summary>
950     ///
Creates a stream and initializes it. Used by PUN internally.
951     ///
</summary>
952     
public PhotonStream(bool write, object[] incomingData)
953     {
954         
this.write = write;
955         
if (incomingData == null)
956         {
957             
this.data = new List<object>();
958         }
959         
else
960         {
961             
this.data = new List<object>(incomingData);
962         }
963     }

964
965     ///
<summary>If true, this client should add data to the stream to send it.</summary>
966     
public bool isWriting
967     {
968         
get { return this.write; }
969     }

970
971     ///
<summary>If true, this client should read data send by another client.</summary>
972     
public bool isReading
973     {
974         
get { return !this.write; }
975     }

976
977     ///
<summary>Count of items in the stream.</summary>
978     
public int Count
979     {
980         
get
981         {
982             
return data.Count;
983         }
984     }

985
986     ///
<summary>Read next piece of data from the stream when isReading is true.</summary>
987     
public object ReceiveNext()
988     {
989         
if (this.write)
990         {
991             Debug.LogError("
Error: you cannot read this stream that you are writing!");
992             
return null;
993         }
994
995         
object obj = this.data[this.currentItem];
996         
this.currentItem++;
997         
return obj;
998     }

999
1000     ///
<summary>Read next piece of data from the stream without advancing the "current" item.</summary>
1001     
public object PeekNext()
1002     {
1003         
if (this.write)
1004         {
1005             Debug.LogError("
Error: you cannot read this stream that you are writing!");
1006             
return null;
1007         }
1008
1009         
object obj = this.data[this.currentItem];
1010         
//this.currentItem++;
1011         
return obj;
1012     }

1013
1014     ///
<summary>Add another piece of data to send it when isWriting is true.</summary>
1015     
public void SendNext(object obj)
1016     {
1017         
if (!this.write)
1018         {
1019             Debug.LogError("
Error: you cannot write/send to this stream that you are reading!");
1020             
return;
1021         }
1022
1023         
this.data.Add(obj);
1024     }

1025
1026     ///
<summary>Turns the stream into a new object[].</summary>
1027     
public object[] ToArray()
1028     {
1029         
return this.data.ToArray();
1030     }

1031
1032     ///
<summary>
1033     ///
Will read or write the value, depending on the stream's isWriting value.
1034     ///
</summary>
1035     
public void Serialize(ref bool myBool)
1036     {
1037         
if (this.write)
1038         {
1039             
this.data.Add(myBool);
1040         }
1041         
else
1042         {
1043             
if (this.data.Count > currentItem)
1044             {
1045                 myBool = (
bool)data[currentItem];
1046                 
this.currentItem++;
1047             }
1048         }
1049     }

1050
1051     ///
<summary>
1052     ///
Will read or write the value, depending on the stream's isWriting value.
1053     ///
</summary>
1054     
public void Serialize(ref int myInt)
1055     {
1056         
if (write)
1057         {
1058             
this.data.Add(myInt);
1059         }
1060         
else
1061         {
1062             
if (this.data.Count > currentItem)
1063             {
1064                 myInt = (
int)data[currentItem];
1065                 currentItem++;
1066             }
1067         }
1068     }

1069
1070     ///
<summary>
1071     ///
Will read or write the value, depending on the stream's isWriting value.
1072     ///
</summary>
1073     
public void Serialize(ref string value)
1074     {
1075         
if (write)
1076         {
1077             
this.data.Add(value);
1078         }
1079         
else
1080         {
1081             
if (this.data.Count > currentItem)
1082             {
1083                 
value = (string)data[currentItem];
1084                 currentItem++;
1085             }
1086         }
1087     }

1088
1089     ///
<summary>
1090     ///
Will read or write the value, depending on the stream's isWriting value.
1091     ///
</summary>
1092     
public void Serialize(ref char value)
1093     {
1094         
if (write)
1095         {
1096             
this.data.Add(value);
1097         }
1098         
else
1099         {
1100             
if (this.data.Count > currentItem)
1101             {
1102                 
value = (char)data[currentItem];
1103                 currentItem++;
1104             }
1105         }
1106     }

1107
1108     ///
<summary>
1109     ///
Will read or write the value, depending on the stream's isWriting value.
1110     ///
</summary>
1111     
public void Serialize(ref short value)
1112     {
1113         
if (write)
1114         {
1115             
this.data.Add(value);
1116         }
1117         
else
1118         {
1119             
if (this.data.Count > currentItem)
1120             {
1121                 
value = (short)data[currentItem];
1122                 currentItem++;
1123             }
1124         }
1125     }

1126
1127     ///
<summary>
1128     ///
Will read or write the value, depending on the stream's isWriting value.
1129     ///
</summary>
1130     
public void Serialize(ref float obj)
1131     {
1132         
if (write)
1133         {
1134             
this.data.Add(obj);
1135         }
1136         
else
1137         {
1138             
if (this.data.Count > currentItem)
1139             {
1140                 obj = (
float)data[currentItem];
1141                 currentItem++;
1142             }
1143         }
1144     }

1145
1146     ///
<summary>
1147     ///
Will read or write the value, depending on the stream's isWriting value.
1148     ///
</summary>
1149     
public void Serialize(ref PhotonPlayer obj)
1150     {
1151         
if (write)
1152         {
1153             
this.data.Add(obj);
1154         }
1155         
else
1156         {
1157             
if (this.data.Count > currentItem)
1158             {
1159                 obj = (PhotonPlayer)data[currentItem];
1160                 currentItem++;
1161             }
1162         }
1163     }

1164
1165     ///
<summary>
1166     ///
Will read or write the value, depending on the stream's isWriting value.
1167     ///
</summary>
1168     
public void Serialize(ref Vector3 obj)
1169     {
1170         
if (write)
1171         {
1172             
this.data.Add(obj);
1173         }
1174         
else
1175         {
1176             
if (this.data.Count > currentItem)
1177             {
1178                 obj = (Vector3)data[currentItem];
1179                 currentItem++;
1180             }
1181         }
1182     }

1183
1184     ///
<summary>
1185     ///
Will read or write the value, depending on the stream's isWriting value.
1186     ///
</summary>
1187     
public void Serialize(ref Vector2 obj)
1188     {
1189         
if (write)
1190         {
1191             
this.data.Add(obj);
1192         }
1193         
else
1194         {
1195             
if (this.data.Count > currentItem)
1196             {
1197                 obj = (Vector2)data[currentItem];
1198                 currentItem++;
1199             }
1200         }
1201     }

1202
1203     ///
<summary>
1204     ///
Will read or write the value, depending on the stream's isWriting value.
1205     ///
</summary>
1206     
public void Serialize(ref Quaternion obj)
1207     {
1208         
if (write)
1209         {
1210             
this.data.Add(obj);
1211         }
1212         
else
1213         {
1214             
if (this.data.Count > currentItem)
1215             {
1216                 obj = (Quaternion)data[currentItem];
1217                 currentItem++;
1218             }
1219         }
1220     }
1221 }

1222
1223
1224 ///
<summary>Provides easy access to most common WebRpc-Response values.</summary>
1225 ///
<remarks>
1226 ///
See method PhotonNetwork.WebRpc.<br/>
1227 ///
Instantiate as new WebRpcResponse(operationResponse) for operationResponse.OperationCode == OperationCode.WebRpc.
1228 ///
</remarks>
1229 public
class WebRpcResponse
1230 {
1231     
public string Name { get; private set; }
1232     ///
<summary>-1 tells you: Got not ReturnCode from WebRpc service.</summary>
1233     
public int ReturnCode { get; private set; }
1234     
public string DebugMessage { get; private set; }
1235     
public Dictionary<string, object> Parameters { get; private set; }
1236
1237     
public WebRpcResponse(OperationResponse response)
1238     {
1239         
object value;
1240         response.Parameters.TryGetValue(ParameterCode.UriPath,
out value);
1241         
this.Name = value as string;
1242
1243         response.Parameters.TryGetValue(ParameterCode.WebRpcReturnCode,
out value);
1244         
this.ReturnCode = (value != null) ? (byte)value : -1;
1245
1246         response.Parameters.TryGetValue(ParameterCode.WebRpcParameters,
out value);
1247         
this.Parameters = value as Dictionary<string, object>;
1248
1249         response.Parameters.TryGetValue(ParameterCode.WebRpcReturnMessage,
out value);
1250         
this.DebugMessage = value as string;
1251     }
1252
1253     
public string ToStringFull()
1254     {
1255         
return string.Format("{0}={2}: {1} \"{3}\"", Name, SupportClass.DictionaryToString(Parameters), ReturnCode, DebugMessage);
1256     }
1257 }

1258
1259 /**

1260 public
class PBitStream
1261 {
1262     List<
byte> streamBytes;
1263     
private int currentByte;
1264     
private int totalBits = 0;
1265
1266     
public int ByteCount
1267     {
1268         
get { return BytesForBits(this.totalBits); }
1269     }
1270
1271     
public int BitCount
1272     {
1273         
get { return this.totalBits; }
1274         
private set { this.totalBits = value; }
1275     }
1276
1277     
public PBitStream()
1278     {
1279         
this.streamBytes = new List<byte>(1);
1280     }
1281
1282     
public PBitStream(int bitCount)
1283     {
1284         
this.streamBytes = new List<byte>(BytesForBits(bitCount));
1285     }
1286
1287     
public PBitStream(IEnumerable<byte> bytes, int bitCount)
1288     {
1289         
this.streamBytes = new List<byte>(bytes);
1290         
this.BitCount = bitCount;
1291     }
1292
1293     
public static int BytesForBits(int bitCount)
1294     {
1295         
if (bitCount <= 0)
1296         {
1297             
return 0;
1298         }
1299
1300         
return ((bitCount - 1) / 8) + 1;
1301     }
1302
1303     
public void Add(bool val)
1304     {
1305         
int bytePos = this.totalBits / 8;
1306         
if (bytePos > this.streamBytes.Count-1 || this.totalBits == 0)
1307         {
1308             
this.streamBytes.Add(0);
1309         }
1310
1311         
if (val)
1312         {
1313             
int currentByteBit = 7 - (this.totalBits % 8);
1314             
this.streamBytes[bytePos] |= (byte)(1 << currentByteBit);
1315         }
1316
1317         
this.totalBits++;
1318     }
1319
1320     
public byte[] ToBytes()
1321     {
1322         
return this.streamBytes.ToArray();
1323     }
1324
1325     
public int Position { get; set; }
1326
1327     
public bool GetNext()
1328     {
1329         
if (this.Position > this.totalBits)
1330         {
1331             
throw new Exception("End of PBitStream reached. Can't read more.");
1332         }
1333
1334         
return Get(this.Position++);
1335     }
1336
1337     
public bool Get(int bitIndex)
1338     {
1339         
int byteIndex = bitIndex / 8;
1340         
int bitInByIndex = 7 - (bitIndex % 8);
1341         
return ((this.streamBytes[byteIndex] & (byte)(1 << bitInByIndex)) > 0);
1342     }
1343
1344     
public void Set(int bitIndex, bool value)
1345     {
1346         
int byteIndex = bitIndex / 8;
1347         
int bitInByIndex = 7 - (bitIndex % 8);
1348         
this.streamBytes[byteIndex] |= (byte)(1 << bitInByIndex);
1349     }
1350 }
1351 **/


----------------------------------------------------------------------------

PhotonNetwork Framework for Unity - Copyright (C) 2011 Exit Games GmbH

developer@exitgames.com

----------------------------------------------------------------------------

\file

Wraps up smaller classes that don't need their own file.

\defgroup publicApi Public API

\brief Groups the most important classes that you need to understand early on.

\defgroup optionalGui Optional Gui Elements

\brief Useful GUI elements for PUN.

Defines the OnPhotonSerializeView method to make it easy to implement correctly for observable scripts.

\ingroup publicApi

Called by PUN several times per second, so that your script can write and read synchronization data for the PhotonView.

This method will be called in scripts that are assigned as Observed component of a PhotonView.

PhotonNetwork.sendRateOnSerialize affects how often this method is called.

PhotonNetwork.sendRate affects how often packages are sent by this client.

Implementing this method, you can customize which data a PhotonView regularly synchronizes.

Your code defines what is being sent (content) and how your data is used by receiving clients.

Unlike other callbacks, OnPhotonSerializeView only gets called when it is assigned

to a PhotonView as PhotonView.observed script.

To make use of this method, the PhotonStream is essential. It will be in "writing" mode" on the

client that controls a PhotonView (PhotonStream.isWriting == true) and in "reading mode" on the

remote clients that just receive that the controlling client sends.

If you skip writing any value into the stream, PUN will skip the update. Used carefully, this can

conserve bandwidth and messages (which have a limit per roomsecond).

Note that OnPhotonSerializeView is not called on remote clients when the sender does not send

any update. This can't be used as "x-times per second Update()".

\ingroup publicApi

Defines all the methods that PUN will call in specific situations, except OnPhotonSerializeView. Implemented by PunBehaviour.

PUN will call these methods on any script that implements them, analog to Unity's events and callbacks.

The situation that triggers the call is described per method.

Please simply extend PunBehaviour to implement individual methods.

OnPhotonSerializeView is NOT called like these callbacks! It's usage frequency is much higher and it is implemented in: IPunObservable.

\ingroup publicApi

Called when the initial connection got established but before you can use the server. OnJoinedLobby() or OnConnectedToMaster() are called when PUN is ready.

This callback is only useful to detect if the server can be reached at all (technically).

Most often, it's enough to implement OnFailedToConnectToPhoton() and OnDisconnectedFromPhoton().

OnJoinedLobby() or OnConnectedToMaster() are called when PUN is ready.

When this is called, the low level connection is established and PUN will send your AppId, the user, etc in the background.

This is not called for transitions from the masterserver to game servers.

Called when the local userclient left a room.

When leaving a room, PUN brings you back to the Master Server.

Before you can use lobbies and join or create rooms, OnJoinedLobby() or OnConnectedToMaster() will get called again.

Called after switching to a new MasterClient when the current one leaves. The former already got removed from the player list.

This is not called when this client enters a room.

Called when a CreateRoom() call failed. The parameter provides ErrorCode and message (as array).

Most likely because the room name is already in use (some other client was faster than you).

PUN logs some info if the PhotonNetwork.logLevel is >= PhotonLogLevel.Informational.

codeAndMsg[0] is an integer ErrorCode and codeAndMsg[1] is a string debug msg.

Called when a JoinRoom() call failed. The parameter provides ErrorCode and message (as array).

Most likely error is that the room does not exist or the room is full (some other client was faster than you).

PUN logs some info if the PhotonNetwork.logLevel is >= PhotonLogLevel.Informational.

codeAndMsg[0] is int ErrorCode. codeAndMsg[1] is string debug msg.

Called when this client created a room and entered it. OnJoinedRoom() will be called as well.

This callback is only called on the client which created a room (see PhotonNetwork.CreateRoom).

As any client might close (or drop connection) anytime, there is a chance that the

creator of a room does not execute OnCreatedRoom.

If you need specific room properties or a "start signal", it is safer to implement

OnMasterClientSwitched() and to make the new MasterClient check the room's state.

Called on entering a lobby on the Master Server. The actual room-list updates will call OnReceivedRoomListUpdate().

Note: When PhotonNetwork.autoJoinLobby is false, OnConnectedToMaster() will be called and the room list won't become available.

While in the lobby, the roomlist is automatically updated in fixed intervals (which you can't modify).

Called after leaving a lobby.

When you leave a lobby, [CreateRoom](@ref PhotonNetwork.CreateRoom) and [JoinRandomRoom](@ref PhotonNetwork.JoinRandomRoom)

automatically refer to the default lobby.

Called if a connect call to the Photon server failed before the connection was established, followed by a call to OnDisconnectedFromPhoton().

This is called when no connection could be established at all.

It differs from OnConnectionFail, which is called when an existing connection fails.

Called when something causes the connection to fail (after it was established), followed by a call to OnDisconnectedFromPhoton().

If the server could not be reached in the first place, OnFailedToConnectToPhoton is called instead.

The reason for the error is provided as DisconnectCause.

Called after disconnecting from the Photon server.

In some cases, other callbacks are called before OnDisconnectedFromPhoton is called.

Examples: OnConnectionFail() and OnFailedToConnectToPhoton().

Called on all scripts on a GameObject (and children) that have been Instantiated using PhotonNetwork.Instantiate.

PhotonMessageInfo parameter provides info about who created the object and when (based off PhotonNetworking.time).

Called for any update of the room listing (no matter if "new" list or "update for known" list). Only called in the Lobby state (on master server).

Not all types of lobbies provive a listing of rooms to the client. Some are silent and specialized for server-side matchmaking.

PUN provides the list of rooms by PhotonNetwork.GetRoomList().

Each item is a RoomInfo which might include custom properties (provided you defined those as lobby-listed when creating a room).

Called when entering a room (by creating or joining it). Called on all clients (including the Master Client).

This method is commonly used to instantiate player characters.

If a match has to be started "actively", you can call an [RPC](@ref PhotonView.RPC) triggered by a user's button-press or a timer.

When this is called, you can usually already access the existing players in the room via PhotonNetwork.playerList.

Also, all custom properties should be already available as Room.customProperties. Check Room.playerCount to find out if

enough players are in the room to start playing.

Called when a remote player entered the room. This PhotonPlayer is already added to the playerlist at this time.

If your game starts with a certain number of players, this callback can be useful to check the

Room.playerCount and find out if you can start.

Called when a remote player left the room. This PhotonPlayer is already removed from the playerlist at this time.

When your client calls PhotonNetwork.leaveRoom, PUN will call this method on the remaining clients.

When a remote client drops connection or gets closed, this callback gets executed. after a timeout

of several seconds.

Called when a JoinRandom() call failed. The parameter provides ErrorCode and message.

Most likely all rooms are full or no rooms are available.

When using multiple lobbies (via JoinLobby or TypedLobby), another lobby might have morefitting rooms.

PUN logs some info if the PhotonNetwork.logLevel is >= PhotonLogLevel.Informational.

codeAndMsg[0] is int ErrorCode. codeAndMsg[1] is string debug msg.

Called after the connection to the master is established and authenticated but only when PhotonNetwork.autoJoinLobby is false.

If you set PhotonNetwork.autoJoinLobby to true, OnJoinedLobby() will be called instead of this.

You can join rooms and create them even without being in a lobby. The default lobby is used in that case.

The list of available rooms won't become available unless you join a lobby via PhotonNetwork.joinLobby.

Because the concurrent user limit was (temporarily) reached, this client is rejected by the server and disconnecting.

When this happens, the user might try again later. You can't create or join rooms in OnPhotonMaxCcuReached(), cause the client will be disconnecting.

You can raise the CCU limits with a new license (when you host yourself) or extended subscription (when using the Photon Cloud).

The Photon Cloud will mail you when the CCU limit was reached. This is also visible in the Dashboard (webpage).

Called when a room's custom properties changed. The propertiesThatChanged contains all that was set via Room.SetCustomProperties.

Since v1.25 this method has one parameter: Hashtable propertiesThatChanged.

Changing properties must be done by Room.SetCustomProperties, which causes this callback locally, too.

Called when custom player-properties are changed. Player and the changed properties are passed as object[].

Since v1.25 this method has one parameter: object[] playerAndUpdatedProps, which contains two entries.

[0] is the affected PhotonPlayer.

[1] is the Hashtable of properties that changed.

We are using a object[] due to limitations of Unity's GameObject.SendMessage (which has only one optional parameter).

Changing properties must be done by PhotonPlayer.SetCustomProperties, which causes this callback locally, too.

Example:

void OnPhotonPlayerPropertiesChanged(object[] playerAndUpdatedProps) {

PhotonPlayer player = playerAndUpdatedProps[0] as PhotonPlayer;

Hashtable props = playerAndUpdatedProps[1] as Hashtable;

...

}

Contains PhotonPlayer and the properties that changed See remarks.

Called when the server sent the response to a FindFriends request and updated PhotonNetwork.Friends.

The friends list is available as PhotonNetwork.Friends, listing name, online state and

the room a user is in (if any).

Called when the custom authentication failed. Followed by disconnect!

Custom Authentication can fail due to user-input, bad tokenssecrets.

If authentication is successful, this method is not called. Implement OnJoinedLobby() or OnConnectedToMaster() (as usual).

During development of a game, it might also fail due to wrong configuration on the server side.

In those cases, logging the debugMessage is very important.

Unless you setup a custom authentication service for your app (in the [Dashboard](https:cloud.exitgames.comdashboard)),

this won't be called!

Contains a debug message why authentication failed. This has to be fixed during development time.

Called by PUN when the response to a WebRPC is available. See PhotonNetwork.WebRPC.

Important: The response.ReturnCode is 0 if Photon was able to reach your web-service.

The content of the response is what your web-service sent. You can create a WebResponse instance from it.

Example: WebRpcResponse webResponse = new WebRpcResponse(operationResponse);

Please note: Class OperationResponse is in a namespace which needs to be "used":

using ExitGames.Client.Photon; includes OperationResponse (and other classes)

The OperationResponse.ReturnCode by Photon is:

0 for "OK"

-3 for "Web-Service not configured" (see Dashboard WebHooks)

-5 for "Web-Service does now have RPC pathname" (at least for Azure)

Called when another player requests ownership of a PhotonView from you (the current owner).

The parameter viewAndPlayer contains:

PhotonView view = viewAndPlayer[0] as PhotonView;

PhotonPlayer requestingPlayer = viewAndPlayer[1] as PhotonPlayer;

The PhotonView is viewAndPlayer[0] and the requesting player is viewAndPlayer[1].

This class adds the property photonView, while logging a warning when your game still uses the networkView.

This class provides a .photonView and all callbacksevents that PUN can call. Override the eventsmethods you want to use.

This class implements IPunCallbacks where the callback methods are described.

By extending this class, you can implement individual methods as override.

Visual Studio and MonoDevelop should provide the list of methods when you begin typing "override".

Your implementation does not have to call "base.method()".

\ingroup publicApi

the documentation for the interface methods becomes inherited when Doxygen builds it.

Called when the initial connection got established but before you can use the server. OnJoinedLobby() or OnConnectedToMaster() are called when PUN is ready.

This callback is only useful to detect if the server can be reached at all (technically).

Most often, it's enough to implement OnFailedToConnectToPhoton() and OnDisconnectedFromPhoton().

OnJoinedLobby() or OnConnectedToMaster() are called when PUN is ready.

When this is called, the low level connection is established and PUN will send your AppId, the user, etc in the background.

This is not called for transitions from the masterserver to game servers.

Called when the local userclient left a room.

When leaving a room, PUN brings you back to the Master Server.

Before you can use lobbies and join or create rooms, OnJoinedLobby() or OnConnectedToMaster() will get called again.

Called after switching to a new MasterClient when the current one leaves. The former already got removed from the player list.

This is not called when this client enters a room.

Called when a CreateRoom() call failed. The parameter provides ErrorCode and message (as array).

Most likely because the room name is already in use (some other client was faster than you).

PUN logs some info if the PhotonNetwork.logLevel is >= PhotonLogLevel.Informational.

codeAndMsg[0] is an integer ErrorCode and codeAndMsg[1] is a string debug msg.

Called when a JoinRoom() call failed. The parameter provides ErrorCode and message (as array).

Most likely error is that the room does not exist or the room is full (some other client was faster than you).

PUN logs some info if the PhotonNetwork.logLevel is >= PhotonLogLevel.Informational.

codeAndMsg[0] is int ErrorCode. codeAndMsg[1] is string debug msg.

Called when this client created a room and entered it. OnJoinedRoom() will be called as well.

This callback is only called on the client which created a room (see PhotonNetwork.CreateRoom).

As any client might close (or drop connection) anytime, there is a chance that the

creator of a room does not execute OnCreatedRoom.

If you need specific room properties or a "start signal", it is safer to implement

OnMasterClientSwitched() and to make the new MasterClient check the room's state.

Called on entering a lobby on the Master Server. The actual room-list updates will call OnReceivedRoomListUpdate().

Note: When PhotonNetwork.autoJoinLobby is false, OnConnectedToMaster() will be called and the room list won't become available.

While in the lobby, the roomlist is automatically updated in fixed intervals (which you can't modify).

Called after leaving a lobby.

When you leave a lobby, [CreateRoom](@ref PhotonNetwork.CreateRoom) and [JoinRandomRoom](@ref PhotonNetwork.JoinRandomRoom)

automatically refer to the default lobby.

Called if a connect call to the Photon server failed before the connection was established, followed by a call to OnDisconnectedFromPhoton().

This is called when no connection could be established at all.

It differs from OnConnectionFail, which is called when an existing connection fails.

Called after disconnecting from the Photon server.

In some cases, other callbacks are called before OnDisconnectedFromPhoton is called.

Examples: OnConnectionFail() and OnFailedToConnectToPhoton().

Called when something causes the connection to fail (after it was established), followed by a call to OnDisconnectedFromPhoton().

If the server could not be reached in the first place, OnFailedToConnectToPhoton is called instead.

The reason for the error is provided as DisconnectCause.

Called on all scripts on a GameObject (and children) that have been Instantiated using PhotonNetwork.Instantiate.

PhotonMessageInfo parameter provides info about who created the object and when (based off PhotonNetworking.time).

Called for any update of the room listing (no matter if "new" list or "update for known" list). Only called in the Lobby state (on master server).

Not all types of lobbies provive a listing of rooms to the client. Some are silent and specialized for server-side matchmaking.

PUN provides the list of rooms by PhotonNetwork.GetRoomList().

Each item is a RoomInfo which might include custom properties (provided you defined those as lobby-listed when creating a room).

Called when entering a room (by creating or joining it). Called on all clients (including the Master Client).

This method is commonly used to instantiate player characters.

If a match has to be started "actively", you can call an [RPC](@ref PhotonView.RPC) triggered by a user's button-press or a timer.

When this is called, you can usually already access the existing players in the room via PhotonNetwork.playerList.

Also, all custom properties should be already available as Room.customProperties. Check Room.playerCount to find out if

enough players are in the room to start playing.

Called when a remote player entered the room. This PhotonPlayer is already added to the playerlist at this time.

If your game starts with a certain number of players, this callback can be useful to check the

Room.playerCount and find out if you can start.

Called when a remote player left the room. This PhotonPlayer is already removed from the playerlist at this time.

When your client calls PhotonNetwork.leaveRoom, PUN will call this method on the remaining clients.

When a remote client drops connection or gets closed, this callback gets executed. after a timeout

of several seconds.

Called when a JoinRandom() call failed. The parameter provides ErrorCode and message.

Most likely all rooms are full or no rooms are available.

When using multiple lobbies (via JoinLobby or TypedLobby), another lobby might have morefitting rooms.

PUN logs some info if the PhotonNetwork.logLevel is >= PhotonLogLevel.Informational.

codeAndMsg[0] is int ErrorCode. codeAndMsg[1] is string debug msg.

Called after the connection to the master is established and authenticated but only when PhotonNetwork.autoJoinLobby is false.

If you set PhotonNetwork.autoJoinLobby to true, OnJoinedLobby() will be called instead of this.

You can join rooms and create them even without being in a lobby. The default lobby is used in that case.

The list of available rooms won't become available unless you join a lobby via PhotonNetwork.joinLobby.

Because the concurrent user limit was (temporarily) reached, this client is rejected by the server and disconnecting.

When this happens, the user might try again later. You can't create or join rooms in OnPhotonMaxCcuReached(), cause the client will be disconnecting.

You can raise the CCU limits with a new license (when you host yourself) or extended subscription (when using the Photon Cloud).

The Photon Cloud will mail you when the CCU limit was reached. This is also visible in the Dashboard (webpage).

Called when a room's custom properties changed. The propertiesThatChanged contains all that was set via Room.SetCustomProperties.

Since v1.25 this method has one parameter: Hashtable propertiesThatChanged.

Changing properties must be done by Room.SetCustomProperties, which causes this callback locally, too.

Called when custom player-properties are changed. Player and the changed properties are passed as object[].

Since v1.25 this method has one parameter: object[] playerAndUpdatedProps, which contains two entries.

[0] is the affected PhotonPlayer.

[1] is the Hashtable of properties that changed.

We are using a object[] due to limitations of Unity's GameObject.SendMessage (which has only one optional parameter).

Changing properties must be done by PhotonPlayer.SetCustomProperties, which causes this callback locally, too.

Example:

void OnPhotonPlayerPropertiesChanged(object[] playerAndUpdatedProps) {

PhotonPlayer player = playerAndUpdatedProps[0] as PhotonPlayer;

Hashtable props = playerAndUpdatedProps[1] as Hashtable;

...

}

Contains PhotonPlayer and the properties that changed See remarks.

Called when the server sent the response to a FindFriends request and updated PhotonNetwork.Friends.

The friends list is available as PhotonNetwork.Friends, listing name, online state and

the room a user is in (if any).

Called when the custom authentication failed. Followed by disconnect!

Custom Authentication can fail due to user-input, bad tokenssecrets.

If authentication is successful, this method is not called. Implement OnJoinedLobby() or OnConnectedToMaster() (as usual).

During development of a game, it might also fail due to wrong configuration on the server side.

In those cases, logging the debugMessage is very important.

Unless you setup a custom authentication service for your app (in the [Dashboard](https:cloud.exitgames.comdashboard)),

this won't be called!

Contains a debug message why authentication failed. This has to be fixed during development time.

Called by PUN when the response to a WebRPC is available. See PhotonNetwork.WebRPC.

Important: The response.ReturnCode is 0 if Photon was able to reach your web-service.

The content of the response is what your web-service sent. You can create a WebResponse instance from it.

Example: WebRpcResponse webResponse = new WebRpcResponse(operationResponse);

Please note: Class OperationResponse is in a namespace which needs to be "used":

using ExitGames.Client.Photon; includes OperationResponse (and other classes)

The OperationResponse.ReturnCode by Photon is:

0 for "OK"

-3 for "Web-Service not configured" (see Dashboard WebHooks)

-5 for "Web-Service does now have RPC pathname" (at least for Azure)

Called when another player requests ownership of a PhotonView from you (the current owner).

The parameter viewAndPlayer contains:

PhotonView view = viewAndPlayer[0] as PhotonView;

PhotonPlayer requestingPlayer = viewAndPlayer[1] as PhotonPlayer;

The PhotonView is viewAndPlayer[0] and the requesting player is viewAndPlayer[1].

Container class for info about a particular message, RPC or update.

\ingroup publicApi

Initializes a new instance of the class.

To create an empty messageinfo only!

Wraps up common room properties needed when you create rooms.

This directly maps to what the fields in the Room class.

Max number of players that can be in the room at any time. 0 means "no limit".

Defines if this room is listed in the lobby. If not, it also is not joined randomly.

A room that is not visible will be excluded from the room lists that are sent to the clients in lobbies.

An invisible room can be joined by name but is excluded from random matchmaking.

Use this to "hide" a room and simulate "private rooms". Players can exchange a roomname and create it

invisble to avoid anyone else joining it.

Defines if this room can be joined at all.

If a room is closed, no player can join this. As example this makes sense when 3 of 4 possible players

start their gameplay early and don't want anyone to join during the game.

The room can still be listed in the lobby (set isVisible to control lobby-visibility).

Removes a user's events and properties from the room when a user leaves.

This makes sense when in rooms where players can't place items in the room and just vanish entirely.

When you disable this, the event history can become too long to load if the room stays in use indefinitely.

Default: true. Cleans up the cache and props of leaving users.

The room's custom properties to set. Use string keys!

Custom room properties are any key-values you need to define the game's setup.

The shorter your keys are, the better.

Example: Map, Mode (could be "m" when used with "Map"), TileSet (could be "t").

Defines the custom room properties that get listed in the lobby.

Name the custom room properties that should be available to clients that are in a lobby.

Use with care. Unless a custom property is essential for matchmaking or user info, it should

not be sent to the lobby, which causes traffic and delays for clients in the lobby.

Default: No custom properties are sent to the lobby.

Time To Live (TTL) for an 'actor' in a room. If a client disconnects, this actor is inactive first and removed after this timeout. In milliseconds.

public int PlayerTtl;

Refers to a specific lobby (and type) on the server.

The name and type are the unique identifier for a lobby.

Join a lobby via PhotonNetwork.JoinLobby(TypedLobby lobby).

The current lobby is stored in PhotonNetwork.lobby.

The name of the Lobby. Can be any string. Default lobby uses "".

The type of the Lobby. Default lobby uses LobbyType.Default.

Aggregates several less-often used options for operation RaiseEvent. See field descriptions for usage details.

Default options: CachingOption: DoNotCache, InterestGroup: 0, targetActors: null, receivers: Others, sequenceChannel: 0.

Defines if the server should simply send the event, put it in the cache or remove events that are like this one.

When using option: SliceSetIndex, SlicePurgeIndex or SlicePurgeUpToIndex, set a CacheSliceIndex. All other options except SequenceChannel get ignored.

The number of the Interest Group to send this to. 0 goes to all users but to get 1 and up, clients must subscribe to the group first.

A list of PhotonPlayer.IDs to send this event to. You can implement events that just go to specific users this way.

Sends the event to All, MasterClient or Others (default). Be careful with MasterClient, as the client might disconnect before it got the event and it gets lost.

Events are ordered per "channel". If you have events that are independent of others, they can go into another sequence or channel.

Events can be forwarded to Webhooks, which can evaluate and use the events to follow the game's state.

Used along with CachingOption SliceSetIndex, SlicePurgeIndex or SlicePurgeUpToIndex if you want to set or purge a specific cache-slice.

Use rarely. The binary message gets encrpted before being sent. Any receiver in the room will be able to decrypt the message, of course.

Defines Photon event-codes as used by PUN.

public const byte SendSerializeReliable = 206; TS: added this but it's not really needed anymore

public const byte DestroyPlayer = 207; TS: added to make others remove all GOs of a player

public const byte AssignMaster = 208; TS: added to assign someone master client (overriding the current)

This container is used in OnPhotonSerializeView() to either provide incoming data of a PhotonView or for you to provide it.

The isWriting property will be true if this client is the "owner" of the PhotonView (and thus the GameObject).

Add data to the stream and it's sent via the server to the other players in a room.

On the receiving side, isWriting is false and the data should be read.

Send as few data as possible to keep connection quality up. An empty PhotonStream will not be sent.

Use either Serialize() for reading and writing or SendNext() and ReceiveNext(). The latter two are just explicit read and

write methods but do about the same work as Serialize(). It's a matter of preference which methods you use.

\ingroup publicApi

byte currentItem = 0; Used to track the next item to receive.

Creates a stream and initializes it. Used by PUN internally.

If true, this client should add data to the stream to send it.

If true, this client should read data send by another client.

Count of items in the stream.

Read next piece of data from the stream when isReading is true.

Read next piece of data from the stream without advancing the "current" item.

this.currentItem++;

Add another piece of data to send it when isWriting is true.

Turns the stream into a new object[].

Will read or write the value, depending on the stream's isWriting value.

Will read or write the value, depending on the stream's isWriting value.

Will read or write the value, depending on the stream's isWriting value.

Will read or write the value, depending on the stream's isWriting value.

Will read or write the value, depending on the stream's isWriting value.

Will read or write the value, depending on the stream's isWriting value.

Will read or write the value, depending on the stream's isWriting value.

Will read or write the value, depending on the stream's isWriting value.

Will read or write the value, depending on the stream's isWriting value.

Will read or write the value, depending on the stream's isWriting value.

Provides easy access to most common WebRpc-Response values.

See method PhotonNetwork.WebRpc.

Instantiate as new WebRpcResponse(operationResponse) for operationResponse.OperationCode == OperationCode.WebRpc.

-1 tells you: Got not ReturnCode from WebRpc service.




Trò chơi Tic-Tac-Toe, game đánh caro full source code 53.596 lượt xem

Gõ tìm kiếm nhanh...